home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 6459 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.8 KB  |  89 lines

  1. Path: rcp6.elan.af.mil!rscernix!danpop
  2. From: danpop@mail.cern.ch (Dan Pop)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: memory allocation using malloc and free
  5. Date: 24 Feb 96 00:43:11 GMT
  6. Organization: CERN European Lab for Particle Physics
  7. Message-ID: <danpop.825122591@rscernix>
  8. References: <4gagll$5rc@bertrand.ccs.carleton.ca> <Pine.SUN.3.91.960222201214.25221B-100000@sunflash.eng.usf.edu>
  9. NNTP-Posting-Host: ues5.cern.ch
  10. X-Newsreader: NN version 6.5.0 #7 (NOV)
  11.  
  12. In <Pine.SUN.3.91.960222201214.25221B-100000@sunflash.eng.usf.edu> "James Black (CS)" <black@eng.usf.edu> writes:
  13.  
  14. >  I put my comments in the code, but the problem simply is that anything 
  15. >that you pass to a variable to a function the variable in the function is 
  16. >local.  If you pass a pointer then the value can change (that the pointer 
  17. >points to), but not the value of the pointer itself.   If you want to 
  18. >change what the value is then you pass a pointer to the pointer.  Passing 
  19. >a pointer to a pointer will solve your problem, as the returned value of 
  20. >the pointer was probably NULL.
  21. >
  22. >On Mon, 19 Feb 1996, Tyler Cope wrote:
  23.  
  24. #ifdef comp_lang_c
  25. #define far    /* :-) */
  26. #include <stdlib.h>
  27. #else
  28. >> #include <process.h>
  29. >> #include <alloc.h>
  30. #endif
  31. >> #include <stdio.h>
  32. >> int main(void)
  33. >> {
  34. >>         void get_mem(unsigned char far *);
  35. >>         void free_mem(unsigned char far *);
  36. >> 
  37. >>         unsigned char far *ptr;
  38. >> 
  39. >>         get_mem(ptr);
  40. >***** should be get_mem (&ptr);
  41. >>         freemem(ptr);
  42. >> 
  43. >>         return(1);
  44. >> }
  45. >> 
  46. >> void get_mem(unsigned char far *fptr)
  47. >***** void get_mem(unsigned char far **fptr)
  48. >> {
  49. >>         if ((fptr = (unsigned char far *)malloc(320*200+1)) == NULL)
  50. >****   if ((*fptr = (unsigned char far *)malloc(320*200+1)) == NULL)
  51. >>         {
  52. >>                 printf("Could not allocate enough memory");
  53. >>                 exit(1);
  54. >>         }
  55. >> }
  56.  
  57. While the proposed fix works (modulo the mistake in the malloc argument), 
  58. it isn't the cleanest solution to the problem.  How about:
  59.  
  60.     ptr = get_mem(); /* in main */
  61.  
  62. and get_mem defined as:
  63.  
  64.     unsigned char far *get_mem(void)
  65.     {
  66.     unsigned char far *fptr = malloc(320U * 200 + 1);
  67.     if (fptr == NULL) {...}
  68.     return fptr;
  69.     }
  70.  
  71. Always avoid pointers to pointers when this is possible.  The resulting 
  72. code would be less error-prone and easier to read and understand.
  73.  
  74. Note that the expression 320 * 200 + 1 will overflow on DOS (or any other
  75. platform with 16-bit int's), which will invoke undefined behaviour.
  76. The easiest fix is to force unsigned arithmetic, as I did in my example.
  77.  
  78. And the usual remark: don't cast the value returned by malloc.  It's not
  79. necessary and potentially dangerous (like any other unnecessary pointer 
  80. cast).
  81.  
  82. Dan
  83. --
  84. Dan Pop
  85. CERN, CN Division
  86. Email: danpop@mail.cern.ch 
  87. Mail:  CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
  88.